﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using Model;
using Interfaces;
using Exceptions;
namespace Controllers
{
    class DBconnection
    {
        // nedenstående er lavet af Morten Støchkel, Anders Madsen og Hung Dinh
        SqlConnection con;
        SqlCommand cmd;
        SqlDataReader datareader;
        string connectionstring;

        //Forbindelsen til vores database bliver oprettet.
        public DBconnection()
        {
            System.Data.SqlClient.SqlConnection com =
                  new System.Data.SqlClient.SqlConnection();

            connectionstring = @"Data Source=ealdb1.eal.local;Initial Catalog=EJL07_DB;User ID=ejl07_usr;Password=Baz1nga7";

            con = new SqlConnection(connectionstring);


            cmd = new SqlCommand();
            cmd.Connection = con;
            cmd.CommandType = CommandType.StoredProcedure;
        }

        //Logik for interaktionen med den stored procedure der tilføjer/opdaterer category data.
        public void Add_Data_Category(string level, string name, string description, string brandCode, string categoryid)
        {
            cmd.CommandText = "Add_Data_Category";
            cmd.Parameters.Clear();
            SqlParameter par = new SqlParameter("@Level", SqlDbType.NVarChar);
            par.Value = level;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@name", SqlDbType.NVarChar);
            par.Value = name;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@description", SqlDbType.NVarChar);
            par.Value = description;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@FK_BrandCode", SqlDbType.NVarChar);
            par.Value = brandCode;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@categoryid", SqlDbType.NVarChar);
            par.Value = categoryid;
            cmd.Parameters.Add(par);

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
            }
            catch (SqlException e)
            {
                throw e;
            }
            finally
            {
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }



        }

        public void Add_Data_Brand(string brandCode, string brandName)
        {
            cmd.CommandText = "Add_Data_Brand";
            cmd.Parameters.Clear();

            SqlParameter par = new SqlParameter("@brandCode", SqlDbType.NVarChar);
            par.Value = brandCode;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@brandName", SqlDbType.NVarChar);
            par.Value = brandName;
            cmd.Parameters.Add(par);

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
            }
            catch (SqlException e)
            {
                throw e;
            }
            finally
            {
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }

        public void Add_Data_Product(string productNumber, string brandCode, string availabilityLevel, string category, string productStatus, decimal price, DateTime launchDate)
        {
            cmd.CommandText = "Add_Data_Product";
            cmd.Parameters.Clear();

            SqlParameter par = new SqlParameter("@productNumber", SqlDbType.NVarChar);
            par.Value = productNumber;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@brandCode", SqlDbType.NVarChar);
            par.Value = brandCode;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@availabilityLevel", SqlDbType.NVarChar);
            par.Value = availabilityLevel;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@category", SqlDbType.NVarChar);
            par.Value = category;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@productStatus", SqlDbType.NVarChar);
            par.Value = productStatus;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@price", SqlDbType.Decimal);
            par.Value = price;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@launchDate", SqlDbType.DateTime);
            par.Value = launchDate;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@InactiveStatus", SqlDbType.Bit);
            par.Value = 1;
            cmd.Parameters.Add(par);

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
            }
            catch (SqlException e)
            {
                throw e;
            }
            finally
            {
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }

        }
        
        public void Add_Data_ProductDetail(string Language, string description, string replacementsNotes, string productNumber)
        {
            cmd.CommandText = "Add_Data_ProductDetail";
            cmd.Parameters.Clear();

            SqlParameter par = new SqlParameter("@language", SqlDbType.NVarChar);
            par.Value = Language;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@description", SqlDbType.NVarChar);
            par.Value = description;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@ReplacementNotes", SqlDbType.NVarChar);
            par.Value = replacementsNotes;
            cmd.Parameters.Add(par);

            par = new SqlParameter("@productNumber", SqlDbType.NVarChar);
            par.Value = productNumber;
            cmd.Parameters.Add(par);

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
            }
            catch (SqlException e)
            {
                throw e;
            }
            finally
            {
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }

        //Dette er vores indlæslogik der i dette eksempel smider alle vores category data
        //fra databasen ind i programmet. Her bruges brandcode til at finde categories.
        public List<ICategory> IndlæsCategoryFraBrand(string brandcodeval)
        {
            SqlDataReader datareader = null;

            List<ICategory> CategoryList = new List<ICategory>();
            int categoryID;
            string level, name, description, brandcode;


            cmd.Parameters.Clear();

            cmd.CommandText = "LoadCategoryFromBrand";

            SqlParameter par = new SqlParameter("@brandcode", SqlDbType.NVarChar);
            par.Value = brandcodeval;
            cmd.Parameters.Add(par);

            try
            {
                con.Open();
                datareader = cmd.ExecuteReader();

                while (datareader.Read())
                {
                    try
                    {
                        categoryID = (int.Parse(datareader["category_id"].ToString()));
                    }
                    catch(Exception ex)
                    {
                        throw new ParseingException("Der skete en fejl ved parsing af CategoryID");                        
                    }


                    level = datareader["level"].ToString();
                    name = datareader["name"].ToString();
                    description = datareader["description"].ToString(); // find denne rækkes årgang
                    brandcode = datareader["FK_Brandcode"].ToString();

                    Category aktuelkategori = new Category(categoryID, level, name, description, brandcode);

                    CategoryList.Add(aktuelkategori);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }

            return CategoryList;
        }

        //Her findes der produkter ved hjælp af categoryID
        public List<IProduct> LoadProductFromCategory(int categoryidval)
        {
            SqlDataReader datareader = null;

            List<IProduct> productList = new List<IProduct>();

            string productnumber, brandcode, availabillitylevel, category, productstatus;
            decimal price;
            DateTime launchdate;

            cmd.Parameters.Clear(); // Tøm parameterlisten, IndlæsMedlem har ingen parametre

            cmd.CommandText = "LoadProductFromCategory";

            SqlParameter par = new SqlParameter("@categoryid", SqlDbType.NVarChar);
            par.Value = categoryidval.ToString();
            cmd.Parameters.Add(par);

            try
            {
                con.Open();
                datareader = cmd.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    productnumber = datareader["productnumber"].ToString();
                    brandcode = datareader["brandcode"].ToString();
                    availabillitylevel = datareader["availibilitylevel"].ToString();
                    category = datareader["FK_category_id"].ToString();
                    productstatus = datareader["productstatus"].ToString();
                    price = decimal.Parse(datareader["price"].ToString());
                    launchdate = DateTime.Parse(datareader["launchdate"].ToString());

                    Product aktueltprodukt = new Product(productnumber, brandcode, availabillitylevel, category, productstatus,
                                                         price, launchdate);

                    productList.Add(aktueltprodukt);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }

            return productList;
        }

        public List<IProductDetail> LoadProductdetailsFromProduct(int sendproductnumber)
        {
            SqlDataReader datareader = null;

            List<IProductDetail> productdetailList = new List<IProductDetail>();

            string description, language, productnumber, replacementnotes;

            cmd.Parameters.Clear(); // Tøm parameterlisten, IndlæsMedlem har ingen parametre

            cmd.CommandText = "LoadProductDetailFromProduct";

            SqlParameter par = new SqlParameter("@ProductNumber", SqlDbType.NVarChar);
            par.Value = sendproductnumber.ToString();
            cmd.Parameters.Add(par);

            try
            {
                con.Open();
                datareader = cmd.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    language = datareader["language"].ToString();
                    description = datareader["description"].ToString();
                    replacementnotes = datareader["replacementnotes"].ToString();
                    productnumber = datareader["fk_productnumber"].ToString();

                    ProductDetail aktuelproductdetail = new ProductDetail(language, description, replacementnotes, productnumber);

                    productdetailList.Add(aktuelproductdetail);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }

            return productdetailList;
        }

        //Her bliver alle brands smidt ind i vores program.
        public List<IBrand> LoadBrands()
        {
            SqlDataReader datareader = null; // skal referere til indlæst data

            List<IBrand> brandList = new List<IBrand>();
            string brandcode, brandname;

            cmd.Parameters.Clear(); // Tøm parameterlisten, IndlæsMedlem har ingen parametre

            cmd.CommandText = "LoadBrands";

            try
            {
                con.Open();
                datareader = cmd.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    brandcode = datareader["brandcode"].ToString();
                    brandname = datareader["brandname"].ToString();
                    Brand aktueltbrand = new Brand(brandcode, brandname);
                    brandList.Add(aktueltbrand);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }

            return brandList;
        }

        public List<IProductDetail> LoadProductDetail()
        {
            SqlDataReader datareader = null; // skal referere til indlæst data

            List<IProductDetail> proddetailList = new List<IProductDetail>();
            string language, description, replacementnotes, productnumber;

            cmd.Parameters.Clear(); // Tøm parameterlisten, IndlæsMedlem har ingen parametre

            cmd.CommandText = "LoadProductDetails";

            try
            {
                con.Open();
                datareader = cmd.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    language = datareader["language"].ToString();
                    description = datareader["description"].ToString();
                    replacementnotes = datareader["replacementnotes"].ToString();
                    productnumber = datareader["fk_productnumber"].ToString();
                    ProductDetail aktueltproddetail = new ProductDetail(language, description,
                                                                        replacementnotes, productnumber);
                    proddetailList.Add(aktueltproddetail);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                if (datareader != null)
                {
                    datareader.Close();
                }
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }

            return proddetailList;
        }

        public List<ICategory> LoadCategories()
        {
            SqlDataReader datareader = null; // skal referere til indlæst data

            List<ICategory> categoryList = new List<ICategory>();
            string level, name, description, brandcode;
            int ID;

            cmd.Parameters.Clear(); // Tøm parameterlisten, IndlæsMedlem har ingen parametre

            cmd.CommandText = "LoadCategory";

            try
            {
                con.Open();
                datareader = cmd.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    ID = int.Parse(datareader["category_id"].ToString());
                    level = datareader["level"].ToString();
                    name = datareader["name"].ToString();
                    description = datareader["description"].ToString();
                    brandcode = datareader["fk_brandcode"].ToString();

                    Category aktuelcategory = new Category(ID, level, name, description, brandcode);
                    categoryList.Add(aktuelcategory);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                if (datareader != null)
                {
                    datareader.Close();
                }
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }

            return categoryList;
        }

        public List<IProduct> LoadProducts()
        {
            SqlDataReader datareader = null; // skal referere til indlæst data

            List<IProduct> productList = new List<IProduct>();
            string productnumber, brandcode, availabilitylevel, category, productstatus;
            decimal price;
            DateTime launchdate;
            cmd.Parameters.Clear(); // Tøm parameterlisten, IndlæsMedlem har ingen parametre

            cmd.CommandText = "LoadProducts";

            try
            {
                con.Open();
                datareader = cmd.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    productnumber = datareader["productnumber"].ToString();
                    brandcode = datareader["brandcode"].ToString();
                    availabilitylevel = datareader["availibilityLevel"].ToString();
                    category = datareader["fk_category_id"].ToString();
                    productstatus = datareader["productstatus"].ToString();
                    price = decimal.Parse(datareader["price"].ToString());
                    launchdate = DateTime.Parse(datareader["launchdate"].ToString());

                    Product aktueltproduct = new Product(productnumber, brandcode, availabilitylevel, category, productstatus,
                                                         price, launchdate);
                    productList.Add(aktueltproduct);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                if (datareader != null)
                {
                    datareader.Close();
                }
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }

            return productList;
        }

        /// <summary>
        /// Gør så vi hurtigt kan indsætte store mængder brandData.
        /// Lavet af Lars Jacobsen
        /// </summary>
        /// <param name="table"></param>
        public void BrandBulkCopy(DataTable table)
        {
            SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionstring);

            bulkCopy.DestinationTableName = "EJL07_DB.Brand";

            try
            {
                // Write from the source to the destination.
                bulkCopy.WriteToServer(table);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

